home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / bstring / bcopy.c < prev    next >
C/C++ Source or Header  |  1992-05-14  |  5KB  |  182 lines

  1. /* 
  2.  * bcopy.c --
  3.  *
  4.  *    Source code for the "bcopy" library routine.
  5.  *
  6.  * Copyright 1988 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /sprite/src/lib/c/bstring/RCS/bcopy.c,v 1.9 92/05/14 18:57:09 kupfer Exp $ SPRITE (Berkeley)";
  18. #endif not lint
  19.  
  20. #include <bstring.h>
  21. #include <machparam.h>
  22.  
  23. /*
  24.  * The following mask is used to detect proper alignment of addresses
  25.  * for doing word operations instead of byte operations.  It is
  26.  * machine-dependent.  If none of the following bits are set in an
  27.  * address, then word-based operations may be used. This value is imported
  28.  * from machparam.h
  29.  */
  30.  
  31. /*
  32.  * Just because we can do loads from half-word addresses on a sun3 doesn't
  33.  * mean we want to.  Make sure the load address is word-aligned and you'll
  34.  * bcopy twice as fast when the dest is greater than the source.
  35.  */
  36. #ifdef sun3
  37. #define WORDMASK 0x3
  38. #else
  39. #define WORDMASK WORD_ALIGN_MASK
  40. #endif
  41.  
  42. /*
  43.  *----------------------------------------------------------------------
  44.  *
  45.  * bcopy --
  46.  *
  47.  *    Copy numBytes from *sourcePtr to *destPtr.  This routine is
  48.  *    optimized to do transfers when sourcePtr and destPtr are both
  49.  *    integer-aligned and point to large areas.
  50.  *
  51.  * Results:
  52.  *    There is no return value.  The memory at *destPtr is modified.
  53.  *
  54.  * Side effects:
  55.  *    None.
  56.  *
  57.  *----------------------------------------------------------------------
  58.  */
  59.  
  60. void
  61. bcopy(sourceVoidPtr, destVoidPtr, numBytes)
  62.     _CONST _VoidPtr sourceVoidPtr; /* Where to copy from */
  63.     _VoidPtr destVoidPtr;    /* Where to copy to */
  64.     register int numBytes;    /* The number of bytes to copy */
  65. {
  66.     register _CONST int *sPtr = (int *) sourceVoidPtr;
  67.     register int *dPtr = (int *) destVoidPtr;
  68.     _CONST char *sourcePtr = sourceVoidPtr;
  69.     char *destPtr = destVoidPtr;
  70.  
  71.     /*
  72.      * If the destination is below the source then it is safe to copy
  73.      * in the forward direction.  Otherwise, we must start at the top
  74.      * and work down, again optimizing for large transfers.
  75.      */
  76.  
  77.     if (dPtr < sPtr) {
  78.     /*
  79.      * If both the source and the destination point to aligned
  80.      * addresses then copy as much as we can in large transfers.  Once
  81.      * we have less than a whole int to copy then it must be done by
  82.      * byte transfers.  Furthermore, use an expanded loop to avoid
  83.      * the overhead of continually testing loop variables.
  84.      */
  85.  
  86.     if (!((((int) sPtr) | (int) dPtr) & WORDMASK)) {
  87.         while (numBytes >= 16*sizeof(int)) {
  88.         dPtr[0] = sPtr[0];
  89.         dPtr[1] = sPtr[1];
  90.         dPtr[2] = sPtr[2];
  91.         dPtr[3] = sPtr[3];
  92.         dPtr[4] = sPtr[4];
  93.         dPtr[5] = sPtr[5];
  94.         dPtr[6] = sPtr[6];
  95.         dPtr[7] = sPtr[7];
  96.         dPtr[8] = sPtr[8];
  97.         dPtr[9] = sPtr[9];
  98.         dPtr[10] = sPtr[10];
  99.         dPtr[11] = sPtr[11];
  100.         dPtr[12] = sPtr[12];
  101.         dPtr[13] = sPtr[13];
  102.         dPtr[14] = sPtr[14];
  103.         dPtr[15] = sPtr[15];
  104.         sPtr += 16;
  105.         dPtr += 16;
  106.         numBytes -= 16*sizeof(int);
  107.         }
  108.         while (numBytes >= sizeof(int)) {
  109.         *dPtr++ = *sPtr++;
  110.         numBytes -= sizeof(int);
  111.         }
  112.         if (numBytes == 0) {
  113.         return;
  114.         }
  115.     }
  116.  
  117.     /*
  118.      * Copy the remaining bytes.
  119.      */
  120.  
  121.     sourcePtr = (char *) sPtr;
  122.     destPtr = (char *) dPtr;
  123.     while (numBytes > 0) {
  124.         *destPtr++ = *sourcePtr++;
  125.         numBytes--;
  126.     }
  127.     } else {
  128.     /*
  129.      * Handle extra bytes at the top that are due to the transfer
  130.      * length rather than pointer misalignment.
  131.      */
  132.     while (numBytes & WORDMASK) {
  133.         numBytes --;
  134.         destPtr[numBytes] = sourcePtr[numBytes];
  135.     }
  136.     sPtr = (int *) (sourcePtr + numBytes);
  137.     dPtr = (int *) (destPtr + numBytes);
  138.  
  139.     if (!((((int) sPtr) | (int) dPtr) & WORDMASK)) {
  140.         while (numBytes >= 16*sizeof(int)) {
  141.         sPtr -= 16;
  142.         dPtr -= 16;
  143.         dPtr[15] = sPtr[15];
  144.         dPtr[14] = sPtr[14];
  145.         dPtr[13] = sPtr[13];
  146.         dPtr[12] = sPtr[12];
  147.         dPtr[11] = sPtr[11];
  148.         dPtr[10] = sPtr[10];
  149.         dPtr[9] = sPtr[9];
  150.         dPtr[8] = sPtr[8];
  151.         dPtr[7] = sPtr[7];
  152.         dPtr[6] = sPtr[6];
  153.         dPtr[5] = sPtr[5];
  154.         dPtr[4] = sPtr[4];
  155.         dPtr[3] = sPtr[3];
  156.         dPtr[2] = sPtr[2];
  157.         dPtr[1] = sPtr[1];
  158.         dPtr[0] = sPtr[0];
  159.         numBytes -= 16*sizeof(int);
  160.         }
  161.         while (numBytes >= sizeof(int)) {
  162.         *--dPtr = *--sPtr;
  163.         numBytes -= sizeof(int);
  164.         }
  165.         if (numBytes == 0) {
  166.         return;
  167.         }
  168.     }
  169.  
  170.     /*
  171.      * Copy the remaining bytes.
  172.      */
  173.  
  174.     destPtr = (char *) dPtr;
  175.     sourcePtr = (char *) sPtr;
  176.     while (numBytes > 0) {
  177.         *--destPtr = *--sourcePtr;
  178.         numBytes--;
  179.     }
  180.     }
  181. }
  182.